/**
 * 字典数据获取
 * <pre>
 * </pre>
 *@author MuYi
 *@date 2023/3/15 21:37
 *@version 1.0
 **/
import {Dict, DictData, DictDataDefaultField, DictMeta} from "./DictDataClass";
import {Tool} from "@/utils/tool";
import {useStore} from "vuex";
/**
 * 获取字典数据
 * <pre>
 *     1 先尝试从store获取
 *     2 名称为"_"开头时时按自定义字典处理
 *     3 request
 * </pre>
 * @param dictMeta
 * @param dict
 */
const tool=Tool.getInstance();

export const requestDict = (dictMeta, dict: Dict) => {
    const typeName: string = dictMeta.type;
    const store = useStore();
    let dictMap=store.state.dicts.dictMap
    if (dictMap.has(typeName)) {
        let dict1 =dictMap.get(typeName);
        dict.type[typeName] = tool.deepClone(dict1.type[typeName]);
        dict.label[typeName] = tool.deepClone(dict1.label[typeName]);
        return null;
    }else
        return dictMeta.request(typeName).then(response => {
            let dicts = getDictDataArrayFromResponse(response, dictMeta);
            return getDicts(store,typeName, dicts, dict);
        })
}

function getDicts(store,typeName, dicts , dict) {
    let newDict = new Dict(typeName);
    if (!(dicts instanceof Array)) {
        dicts = []
    } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
        console.error('后台获取数据非DictData')
        dicts = []
    }
    
    dict.type[typeName].splice(0, Number.MAX_SAFE_INTEGER, ...dicts);
    newDict.type[typeName].splice(0, Number.MAX_SAFE_INTEGER, ...dicts);
    let label = {}
    dicts.forEach(item => {
        label[item.value] = item.label;
    })
    dict.label[typeName] = label
    newDict.label[typeName] = tool.deepClone(label)
    store.dispatch("dicts/set",{"key":typeName,"value":tool.deepClone(newDict)});
    return dicts;
}

/**
 * 由response数据获取字典数据集
 * @param {Object} response 后台获取的字典数据
 * @param {DictMeta} dictMeta 字典元数据
 * @returns {DictData}
 */
const getDictDataArrayFromResponse = (response, dictMeta: DictMeta): DictData[] => {
    const dicts = response.content instanceof Array ? response.content : response
    if (dicts === undefined) {
        console.warn(`试图获取"${dictMeta.type}"的字典，未数组数据集`)
        return []
    }
    return dicts.map(item => convertToDict(item, dictMeta))
}
/**
 * 有一条包含标签、字典值的原始数据获取新的字典对象
 * @param rawData 原始数据
 * @param dictMeta 字典元数据
 */
const convertToDict = (rawData, dictMeta): DictData => {
    const label = determineDictField(rawData, dictMeta.labelField, ...DictDataDefaultField.LABEL)
    const value = determineDictField(rawData, dictMeta.valueField, ...DictDataDefaultField.VALUE)
    return new DictData(rawData[label], rawData[value], rawData)
}

/**
 * 确定字典字段(label或value)名称
 * @param  {Object} rawData  原始数据
 * @param  {...String} fields
 */
const determineDictField = (rawData, ...fields) => {
    return fields.find(f => Object.prototype.hasOwnProperty.call(rawData, f))
}


